home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Turnbull China Bikeride
/
Turnbull China Bikeride - Disc 1.iso
/
DEMON
/
RISCOS2
/
TCP_131S.ARC
/
c
/
NetTime
< prev
next >
Wrap
Text File
|
1994-03-03
|
7KB
|
267 lines
/***************************************************************************
Purpose : Routines for setting KA9Q's time from the remote host.
: Uses the protocol described in RFC 868.
***************************************************************************
: Copyright Giles Todd 1992. All rights reserved.
: The right of Giles Todd to be identified as the author
: of this work has been asserted by him in accordance
: with the Copyrights, Designs and Patents Act, 1988.
: No restrictions on the use of this module with KA9Q.
***************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "Arc.h"
#include "domain.h"
#include "global.h"
#include "mbuf.h"
#include "misc.h"
#include "cmdparse.h"
#include "socket.h"
#include "timer.h"
#include "netuser.h"
#include "udp.h"
int done_set_time = 0; /* have we set the time since this open? */
#define TIME_PORT 37
extern int16 lport; /* local port placeholder */
extern int32 wimp_ver;
/***************************************************************************
Static function declarations.
***************************************************************************/
static int do_server (int argc, char **argv);
static int do_maxcorrect (int argc, char **argv);
static int do_mincorrect (int argc, char **argv);
static int do_read (int argc, char **argv);
static int do_set (int argc, char **argv);
/***************************************************************************
Static data.
***************************************************************************/
static time_t correction = 0; /* difference in seconds */
/* between remote and PC clock */
static int32 server = 0L; /* time server address */
static time_t max_correction = 0; /* !0 is max correction allowed */
static time_t min_correction = 0; /* !0 is min correction allowed */
static BOOL set_clock = FALSE;
static struct timer net_time_t;
static struct socket time_socket;
static struct cmds time_cmds[] =
{
"maxcorrect", do_maxcorrect, 0, 0, NULLCHAR ,
"mincorrect", do_mincorrect, 0, 0, NULLCHAR ,
"read", do_read, 0, 0, NULLCHAR ,
"server", do_server, 0, 0, NULLCHAR ,
"set", do_set, 0, 0, NULLCHAR ,
NULLCHAR ,
};
int dotime (int argc, char *argv[])
{
return(subcmd(time_cmds, argc, argv));
}
/* Display or set the timer server address. */
static int do_server(int argc, char *argv[])
{
int32 n; /* temporary */
if (argc < 2)
{
cwprintf(NULL, "%s\n", inet_ntoa(server));
}
else if (n = resolve(argv[1]), n == 0)
{
cwprintf(NULL, "Time - Bad host %s\n", argv[1]);
return (1);
}
else
{
server = n;
}
return (0);
}
static void no_net_time(void *sk)
{
cwprintf(NULL, "Time - No response from %s\n", inet_ntoa(server));
del_udp((struct socket *) sk);
set_clock = FALSE;
}
time_t RiscTime(time_t *place)
{
BOOL carry = FALSE;
char btime[] = "\x00\x00\x00\x00\x6A\x99\x6E\x33\x00";
char rtime[8], ntime[8], tzname[10];
int diff, loop, temp, tz;
if (wimp_ver < 300)
return(time(place));
os_swi2r(0x43048, NULL, NULL, (int *) tzname, &tz);
rtime[3] = 3;
os_word(14, &rtime[3]);
for (loop = 3; loop < 8; loop++)
{
temp = rtime[loop] - btime[loop] - carry;
ntime[loop] = temp & 0xFF;
carry = ((temp & 0x100) != 0);
}
diff = (*((int *) &ntime[4]));
temp = ((diff / 100) * 256) + (((diff % 100) * 256) + ntime[3]) / 100 + tz / 100;
if (place)
*place = temp;
return(temp);
}
static void time_rec(struct socket *lsock, int16 rcvcnt)
{
int loop;
struct socket fsocket; /* socket address */
struct mbuf *bp;
time_t pctime; /* PC time */
union
{
time_t time;
char bytes[sizeof (time_t)];
} result; /* data from remote */
if (recv_udp(lsock, &fsocket, &bp) != 4)
{
cwprintf(NULL, "TIME: receive failed\n");
stop_timer(&net_time_t);
del_udp(lsock);
done_set_time = FALSE;
return;
}
/* Calculate the correction value. */
loop = 0;
while (pullone(&bp, &result.bytes[3 - loop]) == 1)
loop++;
result.time -= 2208988800U; /* adjust epoch */
pctime = RiscTime(NULL);
correction = result.time - pctime;
cwprintf(NULL, "TIME: correction = %ld seconds\n", correction);
cwprintf(NULL, "Net time (GMT): %s", asctime (gmtime (&result.time)));
cwprintf(NULL, "Local time (GMT): %s", asctime (gmtime (&pctime)));
stop_timer(&net_time_t);
del_udp(lsock);
if (set_clock)
{
char itime[8];
int correction_abs;
correction_abs = (int) labs(correction);
if (max_correction && correction_abs > max_correction)
{
cwprintf(NULL, "TIME: required correction (%ld) greater than maximum (%ld)\n",
correction, max_correction);
correction = 0;
return;
}
if (min_correction && correction_abs < min_correction)
{
cwprintf(NULL, "TIME: required correction (%ld) less than minimum (%ld)\n",
correction, min_correction);
correction = 0;
return;
}
itime[0] = 3;
os_word(14, itime);
time_adj(itime, correction);
os_swi1(0x43047 /* Territory_SetTime */, (int) itime);
correction = 0; /* no need for a correction now */
cwprintf(NULL, "TIME: Arc clock reset\n");
}
set_clock = FALSE;
}
/* Read the time from the remote and set the correction value. */
static int do_read(int argc, char *argv[])
{
struct socket lsocket, fsocket; /* socket address */
if (server == 0L)
{
cwprintf(NULL, "Time - Bad host %s\n", "0.0.0.0");
return (1);
}
if (run_timer(&net_time_t))
{
cwprintf(NULL, "Time - Already asking\n");
return (1);
}
/* Set up the connection. */
fsocket.address = server;
fsocket.port = TIME_PORT;
lsocket.address = ip_addr; /* our ip address */
lsocket.port = lport++; /* next unused port */
open_udp(&lsocket, (void (*)())time_rec);
send_udp(&lsocket, &fsocket, 0, 0, 0, 0, 0, 0);
time_socket = lsocket;
net_time_t.func = no_net_time; /* what to call on timeout */
net_time_t.arg = (void *) &time_socket;
set_timer(&net_time_t, 30000);
start_timer(&net_time_t);
return(0);
}
/* Set the Arc's clock from the time server. */
static int do_set (int argc, char *argv[])
{
if (do_read (0, NULL) != 0)
return (1);
set_clock = TRUE;
return (0);
}
static int do_maxcorrect(int argc, char *argv[])
{
if(argc < 2)
{
cwprintf(NULL, "TIME: maximum correction: %d\n", max_correction);
return 0;
}
max_correction = atoi(argv[1]);
return 0;
}
static int do_mincorrect(int argc, char *argv[])
{
if(argc < 2)
{
cwprintf(NULL, "TIME: minimum correction: %d\n", min_correction);
return 0;
}
min_correction = atoi(argv[1]);
return 0;
}